
# coding: utf-8

# In[91]:


import numpy as np
import pandas as pd
from sklearn.pipeline import Pipeline
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.svm import LinearSVC
from sklearn.feature_extraction.text import TfidfTransformer
from sklearn.multiclass import OneVsRestClassifier
from sklearn.preprocessing import LabelBinarizer
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
import warnings
warnings.filterwarnings("ignore")

train = pd.read_csv("../data/train.csv", delimiter='\t')
test = pd.read_csv("../data/test.csv", delimiter='\t')
train.dropna(inplace=True)
test.dropna(inplace=True)
train = np.array(train.values.tolist())
test = np.array(test.values.tolist())

x_train, y_train = train[:, 1], train[:, 0]
x_test, y_test = test[:, 1], test[:, 0]
lb = LabelBinarizer()
Y = lb.fit_transform(y_train)

def eval_score(preds, labels):
    temp = labels == preds
    temp = temp.astype(int)
    return sum(temp) / len(temp)

def get_eval(name, classifier):
    predicted = lb.inverse_transform(classifier.predict(x_test))
    print("%s: eval score on test dataset: %.3f" % (name, eval_score(predicted, y_test)))
    predicted = lb.inverse_transform(classifier.predict(x_train))
    print("%s: eval score on train dataset: %.3f" % (name, eval_score(predicted, y_train)))


# ## SVM
clf_svm = Pipeline([
    ('vectorizer', CountVectorizer(stop_words="english")),
    ('tfidf', TfidfTransformer()),
    ('clf', OneVsRestClassifier(LinearSVC(class_weight='balanced')))
])

clf_svm.fit(x_train, Y)
get_eval('[SVM]', clf_svm)


# ## Nb
from sklearn.naive_bayes import MultinomialNB
clf_nb = Pipeline([
    ('vectorizer', CountVectorizer(stop_words="english")),
    ('tfidf', TfidfTransformer()),
    ('clf', OneVsRestClassifier(MultinomialNB()))
])
clf_nb.fit(x_train, Y)
get_eval('[nb]', clf_nb)


# ## Random Forest
from sklearn.ensemble import RandomForestClassifier
clf_rf = Pipeline([
    ('vectorizer', CountVectorizer(stop_words="english")),
    ('tfidf', TfidfTransformer()),
    ('clf', OneVsRestClassifier(RandomForestClassifier()))
])
clf_rf.fit(x_train, Y)
get_eval('[random forest]', clf_rf)


# ## NN
# from sklearn.neural_network import MLPClassifier
# clf_nn = Pipeline([
#     ('vectorizer', CountVectorizer(stop_words="english")),
#     ('tfidf', TfidfTransformer()),
#     ('clf', MLPClassifier(hidden_layer_sizes=256))
# ])
# clf_nn.fit(x_train, Y)
# get_eval('[nn]', clf_nn)


# ## Xgboost OneVSrest
from xgboost import XGBClassifier
clf_xgb = Pipeline([
    ('vectorizer', CountVectorizer(stop_words="english")),
    ('tfidf', TfidfTransformer()),
    ('clf', OneVsRestClassifier(XGBClassifier()))
])
clf_xgb.fit(x_train, Y)
get_eval('[xgb oneVSrest]', clf_xgb)


# ## Xgboost Multiclass Classification
label_int = dict([(x, i) for i, x in enumerate(set(y_train.tolist()))])
int_label = dict([(i, x) for i, x in enumerate(set(y_train.tolist()))])
xgb_y_train = [label_int[x] for x in y_train]
xgb_y_test = np.array([label_int[x] for x in y_test])

clf_xgb1 = Pipeline([
    ('vectorizer', CountVectorizer(stop_words="english")),
    ('tfidf', TfidfTransformer()),
    ('clf', XGBClassifier(objective="multi:softmax"))
])
clf_xgb1.fit(x_train, xgb_y_train)

predicted = clf_xgb1.predict(x_test)
print("[xgb multiclass] eval score on test dataset: %.3f" % eval_score(predicted, xgb_y_test))
predicted = clf_xgb1.predict(x_train)
print("xgb multiclass eval score on train dataset: %.3f" % eval_score(predicted, xgb_y_train))


# ## Predict
texts = [
    "smartphone turn off out off suddeni dont know what is this ip6 problem on 2015 , i end up having to shut down the computer i'm pretty sure it was not purchased through the app store"
]
print("svm: ", lb.inverse_transform(clf_xgb.predict(texts)))
print("nb: ", lb.inverse_transform(clf_nb.predict(texts)))
print("rf: ", lb.inverse_transform(clf_rf.predict(texts)))
# print("nn: ", lb.inverse_transform(clf_nn.predict(texts)))
print("xgb oneVSrest: ", lb.inverse_transform(clf_xgb.predict(texts)))
print("xgb multiclass: ", [int_label[t] for t in clf_xgb1.predict(texts)])

